// vector standard header
#pragma once
#ifndef _VECTOR_
#define _VECTOR_
#ifndef RC_INVOKED
#include <xmemory>
#include <stdexcept>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,_STL_WARNING_LEVEL)
 #pragma warning(disable: _STL_DISABLED_WARNINGS)
 #pragma push_macro("new")
 #undef new

_STD_BEGIN
		// TEMPLATE CLASS _Vector_const_iterator
template<class _Myvec>
	class _Vector_const_iterator
		: public _Iterator012<random_access_iterator_tag,
			typename _Myvec::value_type,
			typename _Myvec::difference_type,
			typename _Myvec::const_pointer,
			typename _Myvec::const_reference,
			_Iterator_base>
	{	// iterator for nonmutable vector
public:
	typedef _Vector_const_iterator<_Myvec> _Myiter;
	typedef random_access_iterator_tag iterator_category;

	typedef typename _Myvec::value_type value_type;
	typedef typename _Myvec::difference_type difference_type;
	typedef typename _Myvec::const_pointer pointer;
	typedef typename _Myvec::const_reference reference;
	typedef typename _Myvec::pointer _Tptr;

	_Vector_const_iterator()
		: _Ptr()
		{	// construct with null pointer
		}

	_Vector_const_iterator(_Tptr _Parg, const _Container_base *_Pvector)
		: _Ptr(_Parg)
		{	// construct with pointer _Parg
		this->_Adopt(_Pvector);
		}

	typedef pointer _Unchecked_type;

	_Myiter& _Rechecked(_Unchecked_type _Right)
		{	// reset from unchecked iterator
		_Ptr = _Const_cast(_Right);
		return (*this);
		}

	_Unchecked_type _Unchecked() const
		{	// make an unchecked iterator
		return (_Ptr);
		}

	reference operator*() const
		{	// return designated object
 #if _ITERATOR_DEBUG_LEVEL == 2
		const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
		if (_Mycont == 0
			|| _Ptr == _Tptr()
			|| _Ptr < _Mycont->_Myfirst
			|| _Mycont->_Mylast <= _Ptr)
			{	// report error
			_DEBUG_ERROR("vector iterator not dereferencable");
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE(_Ptr != _Tptr());
		const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
		_SCL_SECURE_VALIDATE(_Mycont != 0);
		_SCL_SECURE_VALIDATE_RANGE(_Mycont->_Myfirst <= _Ptr && _Ptr < _Mycont->_Mylast);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		_Analysis_assume_(_Ptr != _Tptr());

		return (*_Ptr);
		}

	pointer operator->() const
		{	// return pointer to class object
		return (pointer_traits<pointer>::pointer_to(**this));
		}

	_Myiter& operator++()
		{	// preincrement
 #if _ITERATOR_DEBUG_LEVEL == 2
		const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
		if (_Mycont == 0
			|| _Ptr == nullptr_t{}
			|| _Mycont->_Mylast <= _Ptr)
			{	// report error
			_DEBUG_ERROR("vector iterator not incrementable");
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE(_Ptr != _Tptr());
		const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
		_SCL_SECURE_VALIDATE(_Mycont != 0);
		_SCL_SECURE_VALIDATE_RANGE(_Ptr < _Mycont->_Mylast);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		++_Ptr;
		return (*this);
		}

	_Myiter operator++(int)
		{	// postincrement
		_Myiter _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Myiter& operator--()
		{	// predecrement
 #if _ITERATOR_DEBUG_LEVEL == 2
		const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
		if (_Mycont == 0
			|| _Ptr == nullptr_t{}
			|| _Ptr <= _Mycont->_Myfirst)
			{	// report error
			_DEBUG_ERROR("vector iterator not decrementable");
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE(_Ptr != _Tptr());
		const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
		_SCL_SECURE_VALIDATE(_Mycont != 0);
		_SCL_SECURE_VALIDATE_RANGE(_Mycont->_Myfirst < _Ptr);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		--_Ptr;
		return (*this);
		}

	_Myiter operator--(int)
		{	// postdecrement
		_Myiter _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Myiter& operator+=(difference_type _Off)
		{	// increment by integer
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Off != 0)
			{
			const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
			if (_Mycont == 0
				|| _Ptr + _Off < _Mycont->_Myfirst
				|| _Mycont->_Mylast < _Ptr + _Off)
				{
				_DEBUG_ERROR("vector iterator + offset out of range");
				}
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		if (_Off != 0)
			{
			const auto _Mycont = static_cast<const _Myvec *>(this->_Getcont());
			_SCL_SECURE_VALIDATE(_Mycont != 0);
			_SCL_SECURE_VALIDATE_RANGE(_Mycont->_Myfirst <= _Ptr + _Off
				&& _Ptr + _Off <= _Mycont->_Mylast);
			}
 #endif /* _ITERATOR_DEBUG_LEVEL */

		_Ptr += _Off;
		return (*this);
		}

	_Myiter operator+(difference_type _Off) const
		{	// return this + integer
		_Myiter _Tmp = *this;
		return (_Tmp += _Off);
		}

	_Myiter& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

	_Myiter operator-(difference_type _Off) const
		{	// return this - integer
		_Myiter _Tmp = *this;
		return (_Tmp -= _Off);
		}

	difference_type operator-(const _Myiter& _Right) const
		{	// return difference of iterators
		_Compat(_Right);
		return (_Ptr - _Right._Ptr);
		}

	reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}

	bool operator==(const _Myiter& _Right) const
		{	// test for iterator equality
		_Compat(_Right);
		return (_Ptr == _Right._Ptr);
		}

	bool operator!=(const _Myiter& _Right) const
		{	// test for iterator inequality
		return (!(*this == _Right));
		}

	bool operator<(const _Myiter& _Right) const
		{	// test if this < _Right
		_Compat(_Right);
		return (_Ptr < _Right._Ptr);
		}

	bool operator>(const _Myiter& _Right) const
		{	// test if this > _Right
		return (_Right < *this);
		}

	bool operator<=(const _Myiter& _Right) const
		{	// test if this <= _Right
		return (!(_Right < *this));
		}

	bool operator>=(const _Myiter& _Right) const
		{	// test if this >= _Right
		return (!(*this < _Right));
		}

 #if _ITERATOR_DEBUG_LEVEL == 2
	void _Compat(const _Myiter& _Right) const
		{	// test for compatible iterator pair
		if (this->_Getcont() != _Right._Getcont())
			{
			_DEBUG_ERROR("vector iterators incompatible");
			}
		}

 #elif _ITERATOR_DEBUG_LEVEL == 1
	void _Compat(const _Myiter& _Right) const
		{	// test for compatible iterator pair
		_SCL_SECURE_VALIDATE_RANGE(this->_Getcont() == _Right._Getcont());
		}

 #else /* _ITERATOR_DEBUG_LEVEL == 0 */
	void _Compat(const _Myiter&) const
		{	// test for compatible iterator pair
		}
 #endif /* _ITERATOR_DEBUG_LEVEL */

	_Tptr _Ptr;	// pointer to element in vector
	};

template<class _Myvec> inline
	typename _Vector_const_iterator<_Myvec>::_Unchecked_type
		_Unchecked(_Vector_const_iterator<_Myvec> _Iter)
	{	// convert to unchecked
	return (_Iter._Unchecked());
	}

template<class _Myvec> inline
	_Vector_const_iterator<_Myvec>&
		_Rechecked(_Vector_const_iterator<_Myvec>& _Iter,
			typename _Vector_const_iterator<_Myvec>
				::_Unchecked_type _Right)
	{	// convert to checked
	return (_Iter._Rechecked(_Right));
	}

template<class _Myvec> inline
	_Vector_const_iterator<_Myvec> operator+(
		typename _Vector_const_iterator<_Myvec>::difference_type _Off,
		_Vector_const_iterator<_Myvec> _Next)
	{	// add offset to iterator
	return (_Next += _Off);
	}

		// TEMPLATE CLASS _Vector_iterator
template<class _Myvec>
	class _Vector_iterator
		: public _Vector_const_iterator<_Myvec>
	{	// iterator for mutable vector
public:
	typedef _Vector_iterator<_Myvec> _Myiter;
	typedef _Vector_const_iterator<_Myvec> _Mybase;
	typedef random_access_iterator_tag iterator_category;

	typedef typename _Myvec::value_type value_type;
	typedef typename _Myvec::difference_type difference_type;
	typedef typename _Myvec::pointer pointer;
	typedef typename _Myvec::reference reference;

	_Vector_iterator()
		{	// construct with null vector pointer
		}

	_Vector_iterator(pointer _Parg, const _Container_base *_Pvector)
		: _Mybase(_Parg, _Pvector)
		{	// construct with pointer _Parg
		}

	typedef pointer _Unchecked_type;

	_Myiter& _Rechecked(_Unchecked_type _Right)
		{	// reset from unchecked iterator
		this->_Ptr = _Right;
		return (*this);
		}

	_Unchecked_type _Unchecked() const
		{	// make an unchecked iterator
		return (this->_Ptr);
		}

	reference operator*() const
		{	// return designated object
		return ((reference)**(_Mybase *)this);
		}

	pointer operator->() const
		{	// return pointer to class object
		return (pointer_traits<pointer>::pointer_to(**this));
		}

	_Myiter& operator++()
		{	// preincrement
		++*(_Mybase *)this;
		return (*this);
		}

	_Myiter operator++(int)
		{	// postincrement
		_Myiter _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Myiter& operator--()
		{	// predecrement
		--*(_Mybase *)this;
		return (*this);
		}

	_Myiter operator--(int)
		{	// postdecrement
		_Myiter _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Myiter& operator+=(difference_type _Off)
		{	// increment by integer
		*(_Mybase *)this += _Off;
		return (*this);
		}

	_Myiter operator+(difference_type _Off) const
		{	// return this + integer
		_Myiter _Tmp = *this;
		return (_Tmp += _Off);
		}

	_Myiter& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

	_Myiter operator-(difference_type _Off) const
		{	// return this - integer
		_Myiter _Tmp = *this;
		return (_Tmp -= _Off);
		}

	difference_type operator-(const _Mybase& _Right) const
		{	// return difference of iterators
		return (*(_Mybase *)this - _Right);
		}

	reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}
	};

template<class _Myvec> inline
	typename _Vector_iterator<_Myvec>::_Unchecked_type
		_Unchecked(_Vector_iterator<_Myvec> _Iter)
	{	// convert to unchecked
	return (_Iter._Unchecked());
	}

template<class _Myvec> inline
	_Vector_iterator<_Myvec>&
		_Rechecked(_Vector_iterator<_Myvec>& _Iter,
			typename _Vector_iterator<_Myvec>
				::_Unchecked_type _Right)
	{	// convert to checked
	return (_Iter._Rechecked(_Right));
	}

template<class _Myvec> inline
	_Vector_iterator<_Myvec> operator+(
		typename _Vector_iterator<_Myvec>::difference_type _Off,
		_Vector_iterator<_Myvec> _Next)
	{	// add offset to iterator
	return (_Next += _Off);
	}

		// vector TYPE WRAPPERS
template<class _Value_type,
	class _Size_type,
	class _Difference_type,
	class _Pointer,
	class _Const_pointer,
	class _Reference,
	class _Const_reference>
	struct _Vec_iter_types
	{	// wraps types needed by iterators
	typedef _Value_type value_type;
	typedef _Size_type size_type;
	typedef _Difference_type difference_type;
	typedef _Pointer pointer;
	typedef _Const_pointer const_pointer;
	typedef _Reference reference;
	typedef _Const_reference const_reference;
	};

template<class _Ty,
	class _Alloc0>
	struct _Vec_base_types
	{	// types needed for a container base
	typedef _Alloc0 _Alloc;
	typedef _Vec_base_types<_Ty, _Alloc> _Myt;

	typedef _Wrap_alloc<_Alloc> _Alty0;
	typedef typename _Alty0::template rebind<_Ty>::other _Alty;


	typedef typename _If<_Is_simple_alloc<_Alty>::value,
		_Simple_types<typename _Alty::value_type>,
		_Vec_iter_types<typename _Alty::value_type,
			typename _Alty::size_type,
			typename _Alty::difference_type,
			typename _Alty::pointer,
			typename _Alty::const_pointer,
			typename _Alty::reference,
			typename _Alty::const_reference> >::type
		_Val_types;
	};

		// TEMPLATE CLASS _Vector_val
template<class _Val_types>
	class _Vector_val
		: public _Container_base
	{	// base class for vector to hold data
public:
	typedef _Vector_val<_Val_types> _Myt;

	typedef typename _Val_types::value_type value_type;
	typedef typename _Val_types::size_type size_type;
	typedef typename _Val_types::difference_type difference_type;
	typedef typename _Val_types::pointer pointer;
	typedef typename _Val_types::const_pointer const_pointer;
	typedef typename _Val_types::reference reference;
	typedef typename _Val_types::const_reference const_reference;

	typedef _Vector_iterator<_Myt> iterator;
	typedef _Vector_const_iterator<_Myt> const_iterator;

	_Vector_val()
		: _Myfirst(),
		_Mylast(),
		_Myend()
		{	// initialize values
		}

	pointer _Myfirst;	// pointer to beginning of array
	pointer _Mylast;	// pointer to current end of sequence
	pointer _Myend;	// pointer to end of array
	};

		// TEMPLATE CLASS _Vector_alloc
template<class _Alloc_types>
	class _Vector_alloc
	{	// base class for vector to hold allocator
public:
	typedef _Vector_alloc<_Alloc_types> _Myt;
	typedef typename _Alloc_types::_Alloc _Alloc;
	typedef typename _Alloc_types::_Alty _Alty;
	typedef typename _Alloc_types::_Val_types _Val_types;

	typedef typename _Val_types::size_type size_type;
	typedef typename _Val_types::difference_type difference_type;
	typedef typename _Val_types::pointer pointer;
	typedef typename _Val_types::const_pointer const_pointer;

	typedef _Vector_iterator<_Vector_val<_Val_types> > iterator;
	typedef _Vector_const_iterator<_Vector_val<_Val_types> > const_iterator;

 #if _ITERATOR_DEBUG_LEVEL == 0
	_Vector_alloc()
		: _Mypair(_Zero_then_variadic_args_t())
		{	// default construct allocator
		}

	template<class _Any_alloc,
		class = enable_if_t<!is_same<decay_t<_Any_alloc>, _Myt>::value> >
		_Vector_alloc(_Any_alloc&& _Al)
		: _Mypair(_One_then_variadic_args_t(),
			_STD forward<_Any_alloc>(_Al))
		{	// construct allocator from _Al
		}

	void _Copy_alloc(const _Alty& _Al)
		{	// replace old allocator
		_Pocca(_Getal(), _Al);
		}

	void _Move_alloc(_Alty& _Al)
		{	// replace old allocator
		_Pocma(_Getal(), _Al);
		}

 #else /* ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ // vvv _ITERATOR_DEBUG_LEVEL != 0 vvv */
	_Vector_alloc()
		: _Mypair(_Zero_then_variadic_args_t())
		{	// default construct allocator
		_Alloc_proxy();
		}

	template<class _Any_alloc,
		class = enable_if_t<!is_same<decay_t<_Any_alloc>, _Myt>::value> >
		_Vector_alloc(_Any_alloc&& _Al)
		: _Mypair(_One_then_variadic_args_t(),
			_STD forward<_Any_alloc>(_Al))
		{	// construct allocator from _Al
		_Alloc_proxy();
		}

	~_Vector_alloc() _NOEXCEPT
		{	// destroy proxy
		_Free_proxy();
		}

	void _Copy_alloc(const _Alty& _Al)
		{	// replace old allocator
		const bool _Reload = _Alty::propagate_on_container_copy_assignment::value && _Getal() != _Al;

		if (_Reload)
			{
			_Free_proxy();
			}

		_Pocca(_Getal(), _Al);

		if (_Reload)
			{
			_Alloc_proxy();
			}
		}

	void _Move_alloc(_Alty& _Al)
		{	// replace old allocator
		const bool _Reload = _Alty::propagate_on_container_move_assignment::value && _Getal() != _Al;

		if (_Reload)
			{
			_Free_proxy();
			}

		_Pocma(_Getal(), _Al);

		if (_Reload)
			{
			_Alloc_proxy();
			}
		}

	void _Alloc_proxy()
		{	// construct proxy
		typename _Alty::template rebind<_Container_proxy>::other
			_Alproxy(_Getal());
		_Myproxy() = _Unfancy(_Alproxy.allocate(1));
		_Alproxy.construct(_Myproxy(), _Container_proxy());
		_Myproxy()->_Mycont = _STD addressof(_Get_data());
		}

	void _Free_proxy()
		{	// destroy proxy
		typename _Alty::template rebind<_Container_proxy>::other
			_Alproxy(_Getal());
		_Orphan_all();
		_Alproxy.destroy(_Myproxy());
		_Alproxy.deallocate(_Alproxy.address(*_Myproxy()), 1);
		_Myproxy() = 0;
		}

	_Iterator_base12 **_Getpfirst() const
		{	// get address of iterator chain
		return (_Get_data()._Getpfirst());
		}

	_Container_proxy * & _Myproxy() _NOEXCEPT
		{	// return reference to _Myproxy
		return (_Get_data()._Myproxy);
		}

	_Container_proxy * const & _Myproxy() const _NOEXCEPT
		{	// return const reference to _Myproxy
		return (_Get_data()._Myproxy);
		}
 #endif /* _ITERATOR_DEBUG_LEVEL == 0 */

	void _Orphan_all()
		{	// orphan all iterators
		_Get_data()._Orphan_all();
		}

	void _Swap_all(_Myt& _Right)
		{	// swap all iterators
		_Get_data()._Swap_all(_Right._Get_data());
		}

	_Alty& _Getal() _NOEXCEPT
		{	// return reference to allocator
		return (_Mypair._Get_first());
		}

	const _Alty& _Getal() const _NOEXCEPT
		{	// return const reference to allocator
		return (_Mypair._Get_first());
		}

	_Vector_val<_Val_types>& _Get_data() _NOEXCEPT
		{	// return reference to _Vector_val
		return (_Mypair._Get_second());
		}

	const _Vector_val<_Val_types>& _Get_data() const _NOEXCEPT
		{	// return const reference to _Vector_val
		return (_Mypair._Get_second());
		}

	pointer& _Myfirst() _NOEXCEPT
		{	// return reference to _Myfirst
		return (_Get_data()._Myfirst);
		}

	const pointer& _Myfirst() const _NOEXCEPT
		{	// return const reference to _Myfirst
		return (_Get_data()._Myfirst);
		}

	pointer& _Mylast() _NOEXCEPT
		{	// return reference to _Mylast
		return (_Get_data()._Mylast);
		}

	const pointer& _Mylast() const _NOEXCEPT
		{	// return const reference to _Mylast
		return (_Get_data()._Mylast);
		}

	pointer& _Myend() _NOEXCEPT
		{	// return reference to _Myend
		return (_Get_data()._Myend);
		}

	const pointer& _Myend() const _NOEXCEPT
		{	// return const reference to _Myend
		return (_Get_data()._Myend);
		}

private:
	_Compressed_pair<_Alty, _Vector_val<_Val_types> > _Mypair;
	};

		// FUNCTION TEMPLATE _Unfancy_maybe_null
template<class _Ptrty> inline
	auto _Unfancy_maybe_null(_Ptrty _Ptr)
	{	// converts from a (potentially null) fancy pointer to a plain pointer
	return (_Ptr ? _STD addressof(*_Ptr) : nullptr_t{});
	}

template<class _Ty> inline
	_Ty * _Unfancy_maybe_null(_Ty * _Ptr)
	{	// do nothing for plain pointers
	return (_Ptr);
	}

		// TEMPLATE CLASS vector
template<class _Ty,
	class _Alloc = allocator<_Ty> >
	class vector
		: public _Vector_alloc<_Vec_base_types<_Ty, _Alloc> >
	{	// varying size array of values
private:
	typedef _Vector_alloc<_Vec_base_types<_Ty, _Alloc> > _Mybase;
	typedef typename _Mybase::_Alty _Alty;

public:
	typedef _Ty value_type;
	typedef _Alloc allocator_type;
	typedef typename _Mybase::pointer pointer;
	typedef typename _Mybase::const_pointer const_pointer;
	typedef _Ty& reference;
	typedef const _Ty& const_reference;
	typedef typename _Mybase::size_type size_type;
	typedef typename _Mybase::difference_type difference_type;
	typedef typename _Mybase::iterator iterator;
	typedef typename _Mybase::const_iterator const_iterator;
	typedef _STD reverse_iterator<iterator> reverse_iterator;
	typedef _STD reverse_iterator<const_iterator> const_reverse_iterator;

	vector() _NOEXCEPT_OP(is_nothrow_default_constructible<_Alloc>::value)
		: _Mybase()
		{	// construct empty vector
		}

	explicit vector(const _Alloc& _Al) _NOEXCEPT
		: _Mybase(_Al)
		{	// construct empty vector, allocator
		}

	explicit vector(_CRT_GUARDOVERFLOW const size_type _Count, const _Alloc& _Al = _Alloc())
		: _Mybase(_Al)
		{	// construct from _Count * _Ty(), optional allocator
		if (_Buy(_Count))
			{	// nonzero, fill it
			_TRY_BEGIN
			this->_Mylast() = _Udefault(this->_Myfirst(), _Count);
			_CATCH_ALL
			_Tidy();
			_RERAISE;
			_CATCH_END
			}
		}

	vector(_CRT_GUARDOVERFLOW const size_type _Count, const _Ty& _Val, const _Alloc& _Al = _Alloc())
		: _Mybase(_Al)
		{	// construct from _Count * _Val, optional allocator
		if (_Buy(_Count))
			{	// nonzero, fill it
			_TRY_BEGIN
			this->_Mylast() = _Ufill(this->_Myfirst(), _Count, _Val);
			_CATCH_ALL
			_Tidy();
			_RERAISE;
			_CATCH_END
			}
		}

private:
	template<class _Iter>
		void _Range_construct_or_tidy(_Iter _First, _Iter _Last, input_iterator_tag)
		{	// initialize with [_First, _Last), avoid leaking, input iterators
		_TRY_BEGIN
		for (; _First != _Last; ++_First)
			{
			emplace_back(*_First);	// performance note: emplace_back()'s strong guarantee is unnecessary here
			}
		_CATCH_ALL
		_Tidy();
		_RERAISE;
		_CATCH_END
		}

	template<class _Iter>
		void _Range_construct_or_tidy(_Iter _First, _Iter _Last, forward_iterator_tag)
		{	// initialize with [_First, _Last), avoid leaking, forward iterators
		if (_Buy(_STD distance(_First, _Last)))
			{	// nonzero, fill it
			_TRY_BEGIN
			this->_Mylast() = _Ucopy(_First, _Last, this->_Myfirst());
			_CATCH_ALL
			_Tidy();
			_RERAISE;
			_CATCH_END
			}
		}

public:
	template<class _Iter,
		class = enable_if_t<_Is_iterator<_Iter>::value>>
		vector(_Iter _First, _Iter _Last, const _Alloc& _Al = _Alloc())
		: _Mybase(_Al)
		{	// construct from [_First, _Last) with optional allocator
		_DEBUG_RANGE(_First, _Last);
		_Range_construct_or_tidy(_Unchecked(_First), _Unchecked(_Last), _Iter_cat_t<_Iter>{});
		}

	vector(initializer_list<_Ty> _Ilist, const _Alloc& _Al = _Alloc())
		: _Mybase(_Al)
		{	// construct from initializer_list, optional allocator
		_Range_construct_or_tidy(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{});
		}

	vector(const vector& _Right)
		: _Mybase(_Right._Getal().select_on_container_copy_construction())
		{	// construct by copying _Right
		if (_Buy(_Right.size()))
			{	// nonzero, fill it
			_TRY_BEGIN
			this->_Mylast() = _Ucopy(_Right._Myfirst(), _Right._Mylast(), this->_Myfirst());
			_CATCH_ALL
			_Tidy();
			_RERAISE;
			_CATCH_END
			}
		}

	vector(const vector& _Right, const _Alloc& _Al)
		: _Mybase(_Al)
		{	// construct by copying _Right, allocator
		if (_Buy(_Right.size()))
			{	// nonzero, fill it
			_TRY_BEGIN
			this->_Mylast() = _Ucopy(_Right._Myfirst(), _Right._Mylast(), this->_Myfirst());
			_CATCH_ALL
			_Tidy();
			_RERAISE;
			_CATCH_END
			}
		}

private:
	void _Move_from(vector&& _Right, true_type)
		{	// move from _Right, stealing its contents
		this->_Swap_all(_Right);

		this->_Myfirst() = _Right._Myfirst();
		this->_Mylast() = _Right._Mylast();
		this->_Myend() = _Right._Myend();

		_Right._Myfirst() = pointer();
		_Right._Mylast() = pointer();
		_Right._Myend() = pointer();
		}

	void _Move_from(vector&& _Right, false_type)
		{	// move from _Right, possibly moving its contents
		if (this->_Getal() == _Right._Getal())
			{
			_Move_from(_STD move(_Right), true_type{});
			}
		else if (_Buy(_Right.size()))
			{	// nonzero, fill it
			this->_Mylast() = _Umove(_Right._Myfirst(), _Right._Mylast(), this->_Myfirst());
			}
		}

public:
	vector(vector&& _Right) _NOEXCEPT
		: _Mybase(_STD move(_Right._Getal()))
		{	// construct by moving _Right
		_Move_from(_STD move(_Right), true_type{});
		}

	vector(vector&& _Right, const _Alloc& _Al)
		: _Mybase(_Al)
		{	// construct by moving _Right, allocator
		_TRY_BEGIN
		// performance note: partially unnecessary EH machinery for stateful allocators
		_Move_from(_STD move(_Right), typename _Alty::is_always_equal{});
		_CATCH_ALL
		_Tidy();
		_RERAISE;
		_CATCH_END
		}

	vector& operator=(vector&& _Right)
		_NOEXCEPT_OP(_Alty::propagate_on_container_move_assignment::value || _Alty::is_always_equal::value)
		{	// assign by moving _Right
		if (this != _STD addressof(_Right))
			{	// different, assign it
			_Tidy();
			this->_Move_alloc(_Right._Getal());
			_Move_from(_STD move(_Right), _Disjunction_t<
				typename _Alty::propagate_on_container_move_assignment,
				typename _Alty::is_always_equal>{});
			}
		return (*this);
		}

	~vector() _NOEXCEPT
		{	// destroy the object
		_Tidy();
		}

private:
	template<class... _Valty>
		void _Emplace_back_with_unused_capacity(_Valty&&... _Val)
		{	// insert by perfectly forwarding into element at end, provide strong guarantee
			// Pre: _Has_unused_capacity()
		this->_Getal().construct(_Unfancy(this->_Mylast()), _STD forward<_Valty>(_Val)...);
		_Orphan_range(this->_Mylast(), this->_Mylast());
		++this->_Mylast();
		}

public:
	template<class... _Valty>
		void emplace_back(_Valty&&... _Val)
		{	// insert by perfectly forwarding into element at end, provide strong guarantee
		if (_Has_unused_capacity())
			{
			_Emplace_back_with_unused_capacity(_STD forward<_Valty>(_Val)...);
			}
		else
			{	// reallocate
			const size_type _Oldsize = size();

			if (_Oldsize == max_size())
				{
				_Xlength();
				}

			const size_type _Newsize = _Oldsize + 1;
			const size_type _Newcapacity = _Calculate_growth(_Newsize);
			bool _Emplaced = false;
			const pointer _Newvec = this->_Getal().allocate(_Newcapacity);

			_TRY_BEGIN
			this->_Getal().construct(_Unfancy(_Newvec + _Oldsize), _STD forward<_Valty>(_Val)...);
			_Emplaced = true;
			_Umove_if_noexcept(this->_Myfirst(), this->_Mylast(), _Newvec);
			_CATCH_ALL
			if (_Emplaced)
				{
				this->_Getal().destroy(_Unfancy(_Newvec + _Oldsize));
				}

			this->_Getal().deallocate(_Newvec, _Newcapacity);
			_RERAISE;
			_CATCH_END

			_Change_array(_Newvec, _Newsize, _Newcapacity);
			}
		}

	void push_back(const _Ty& _Val)
		{	// insert element at end, provide strong guarantee
		emplace_back(_Val);
		}

	void push_back(_Ty&& _Val)
		{	// insert by moving into element at end, provide strong guarantee
		emplace_back(_STD move(_Val));
		}

	template<class... _Valty>
		iterator emplace(const_iterator _Where, _Valty&&... _Val)
		{	// insert by perfectly forwarding _Val at _Where
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Where._Getcont() != _STD addressof(this->_Get_data())
			|| _Where._Ptr < this->_Myfirst()
			|| this->_Mylast() < _Where._Ptr)
			{
			_DEBUG_ERROR("vector emplace iterator outside range");
			}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		const size_type _Whereoff = _Where._Ptr - this->_Myfirst();
		const bool _At_back = _Where._Ptr == this->_Mylast();

		if (!_Has_unused_capacity())
			{	// reallocate
			const size_type _Oldsize = size();

			if (_Oldsize == max_size())
				{
				_Xlength();
				}

			const size_type _Newsize = _Oldsize + 1;
			const size_type _Newcapacity = _Calculate_growth(_Newsize);

			const pointer _Newvec = this->_Getal().allocate(_Newcapacity);
			const pointer _Constructed_last = _Newvec + _Whereoff + 1;
			pointer _Constructed_first = _Constructed_last;

			_TRY_BEGIN
			this->_Getal().construct(_Unfancy(_Newvec + _Whereoff), _STD forward<_Valty>(_Val)...);
			_Constructed_first = _Newvec + _Whereoff;

			if (_At_back)
				{	// provide strong guarantee
				_Umove_if_noexcept(this->_Myfirst(), this->_Mylast(), _Newvec);
				}
			else
				{	// provide basic guarantee
				_Umove(this->_Myfirst(), _Where._Ptr, _Newvec);
				_Constructed_first = _Newvec;
				_Umove(_Where._Ptr, this->_Mylast(), _Newvec + _Whereoff + 1);
				}
			_CATCH_ALL
			_Destroy(_Constructed_first, _Constructed_last);
			this->_Getal().deallocate(_Newvec, _Newcapacity);
			_RERAISE;
			_CATCH_END

			_Change_array(_Newvec, _Newsize, _Newcapacity);
			}
		else if (_At_back)
			{	// provide strong guarantee
			_Emplace_back_with_unused_capacity(_STD forward<_Valty>(_Val)...);
			}
		else
			{
			_Ty _Obj(_STD forward<_Valty>(_Val)...);	// handle aliasing
			// after constructing _Obj, provide basic guarantee
			const pointer _Oldlast = this->_Mylast();
			_Orphan_range(_Where._Ptr, _Oldlast);
			this->_Getal().construct(_Unfancy(_Oldlast), _STD move(_Oldlast[-1]));
			++this->_Mylast();
			_Move_backward_unchecked(_Where._Ptr, _Oldlast - 1, _Oldlast);
			*_Where._Ptr = _STD move(_Obj);
			}

		return (begin() + _Whereoff);
		}

	iterator insert(const_iterator _Where, const _Ty& _Val)
		{	// insert _Val at _Where
		return (emplace(_Where, _Val));
		}

	iterator insert(const_iterator _Where, _Ty&& _Val)
		{	// insert by moving _Val at _Where
		return (emplace(_Where, _STD move(_Val)));
		}

	iterator insert(const_iterator _Where, _CRT_GUARDOVERFLOW const size_type _Count, const _Ty& _Val)
		{	// insert _Count * _Val at _Where
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Where._Getcont() != _STD addressof(this->_Get_data())
			|| _Where._Ptr < this->_Myfirst()
			|| this->_Mylast() < _Where._Ptr)
			{
			_DEBUG_ERROR("vector insert iterator outside range");
			}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		const size_type _Whereoff = _Where._Ptr - this->_Myfirst();
		const bool _One_at_back = _Count == 1 && _Where._Ptr == this->_Mylast();

		if (_Count == 0)
			{	// nothing to do, avoid invalidating iterators
			}
		else if (_Count > _Unused_capacity())
			{	// reallocate
			const size_type _Oldsize = size();

			if (_Count > max_size() - _Oldsize)
				{
				_Xlength();
				}

			const size_type _Newsize = _Oldsize + _Count;
			const size_type _Newcapacity = _Calculate_growth(_Newsize);

			const pointer _Newvec = this->_Getal().allocate(_Newcapacity);
			const pointer _Constructed_last = _Newvec + _Whereoff + _Count;
			pointer _Constructed_first = _Constructed_last;

			_TRY_BEGIN
			_Ufill(_Newvec + _Whereoff, _Count, _Val);
			_Constructed_first = _Newvec + _Whereoff;

			if (_One_at_back)
				{	// provide strong guarantee
				_Umove_if_noexcept(this->_Myfirst(), this->_Mylast(), _Newvec);
				}
			else
				{	// provide basic guarantee
				_Umove(this->_Myfirst(), _Where._Ptr, _Newvec);
				_Constructed_first = _Newvec;
				_Umove(_Where._Ptr, this->_Mylast(), _Newvec + _Whereoff + _Count);
				}
			_CATCH_ALL
			_Destroy(_Constructed_first, _Constructed_last);
			this->_Getal().deallocate(_Newvec, _Newcapacity);
			_RERAISE;
			_CATCH_END

			_Change_array(_Newvec, _Newsize, _Newcapacity);
			}
		else if (_One_at_back)
			{	// provide strong guarantee
			_Emplace_back_with_unused_capacity(_Val);
			}
		else
			{	// provide basic guarantee
			const _Ty _Tmp = _Val;	// handle aliasing
			const pointer _Oldlast = this->_Mylast();
			const size_type _Affected_elements = _Oldlast - _Where._Ptr;
			_Orphan_range(_Where._Ptr, _Oldlast);

			if (_Count > _Affected_elements)
				{	// new stuff spills off end
				this->_Mylast() = _Ufill(_Oldlast, _Count - _Affected_elements, _Tmp);
				this->_Mylast() = _Umove(_Where._Ptr, _Oldlast, this->_Mylast());
				_Fill_unchecked(_Where._Ptr, _Oldlast, _Tmp);
				}
			else
				{	// new stuff can all be assigned
				this->_Mylast() = _Umove(_Oldlast - _Count, _Oldlast, _Oldlast);
				_Move_backward_unchecked(_Where._Ptr, _Oldlast - _Count, _Oldlast);
				_Fill_unchecked(_Where._Ptr, _Where._Ptr + _Count, _Tmp);
				}
			}

		return (begin() + _Whereoff);
		}

private:
	template<class _Iter>
		void _Insert_range(const_iterator _Where, _Iter _First, _Iter _Last, input_iterator_tag)
		{	// insert [_First, _Last) at _Where, input iterators
		if (_First == _Last)
			{
			return;	// nothing to do, avoid invalidating iterators
			}

		const size_type _Whereoff = _Where._Ptr - this->_Myfirst();
		const size_type _Oldsize = size();

		// For one-at-back, provide strong guarantee.
		// Otherwise, provide basic guarantee (despite N4606 23.3.11.5 [vector.modifiers]/1).
		// Performance note: except for one-at-back, emplace_back()'s strong guarantee is unnecessary here.

		for (; _First != _Last; ++_First)
			{
			emplace_back(*_First);
			}

		_Orphan_range(this->_Myfirst() + _Whereoff, this->_Myfirst() + _Oldsize);

		_Rotate_unchecked(this->_Myfirst() + _Whereoff, this->_Myfirst() + _Oldsize, this->_Mylast());
		}

	template<class _Iter>
		void _Insert_range(const_iterator _Where, _Iter _First, _Iter _Last, forward_iterator_tag)
		{	// insert [_First, _Last) at _Where, forward iterators
		const size_type _Count = _STD distance(_First, _Last);
		const size_type _Whereoff = _Where._Ptr - this->_Myfirst();
		const bool _One_at_back = _Count == 1 && _Where._Ptr == this->_Mylast();

		if (_Count == 0)
			{	// nothing to do, avoid invalidating iterators
			}
		else if (_Count > _Unused_capacity())
			{	// reallocate
			const size_type _Oldsize = size();

			if (_Count > max_size() - _Oldsize)
				{
				_Xlength();
				}

			const size_type _Newsize = _Oldsize + _Count;
			const size_type _Newcapacity = _Calculate_growth(_Newsize);

			const pointer _Newvec = this->_Getal().allocate(_Newcapacity);
			const pointer _Constructed_last = _Newvec + _Whereoff + _Count;
			pointer _Constructed_first = _Constructed_last;

			_TRY_BEGIN
			_Ucopy(_First, _Last, _Newvec + _Whereoff);
			_Constructed_first = _Newvec + _Whereoff;

			if (_One_at_back)
				{	// provide strong guarantee
				_Umove_if_noexcept(this->_Myfirst(), this->_Mylast(), _Newvec);
				}
			else
				{	// provide basic guarantee
				_Umove(this->_Myfirst(), _Where._Ptr, _Newvec);
				_Constructed_first = _Newvec;
				_Umove(_Where._Ptr, this->_Mylast(), _Newvec + _Whereoff + _Count);
				}
			_CATCH_ALL
			_Destroy(_Constructed_first, _Constructed_last);
			this->_Getal().deallocate(_Newvec, _Newcapacity);
			_RERAISE;
			_CATCH_END

			_Change_array(_Newvec, _Newsize, _Newcapacity);
			}
		else
			{	// Attempt to provide the strong guarantee for EmplaceConstructible failure.
				// If we encounter copy/move construction/assignment failure, provide the basic guarantee.
				// (For one-at-back, this provides the strong guarantee.)

			const pointer _Oldlast = this->_Mylast();
			const size_type _Affected_elements = _Oldlast - _Where._Ptr;

			if (_Count < _Affected_elements)
				{	// some affected elements must be assigned
				this->_Mylast() = _Umove(_Oldlast - _Count, _Oldlast, _Oldlast);
				_Move_backward_unchecked(_Where._Ptr, _Oldlast - _Count, _Oldlast);
				_Destroy(_Where._Ptr, _Where._Ptr + _Count);

				_TRY_BEGIN
				_Ucopy(_First, _Last, _Where._Ptr);
				_CATCH_ALL
				// glue the broken pieces back together

					_TRY_BEGIN
					_Umove(_Where._Ptr + _Count, _Where._Ptr + 2 * _Count, _Where._Ptr);
					_CATCH_ALL
					// vaporize the detached piece
					_Orphan_range(_Where._Ptr, _Oldlast);
					_Destroy(_Where._Ptr + _Count, this->_Mylast());
					this->_Mylast() = _Where._Ptr;
					_RERAISE;
					_CATCH_END

					_Move_unchecked(_Where._Ptr + 2 * _Count, this->_Mylast(), _Where._Ptr + _Count);
					_Destroy(_Oldlast, this->_Mylast());
					this->_Mylast() = _Oldlast;
				_RERAISE;
				_CATCH_END
				}
			else
				{	// affected elements don't overlap before/after
				const pointer _Relocated = _Where._Ptr + _Count;
				this->_Mylast() = _Umove(_Where._Ptr, _Oldlast, _Relocated);
				_Destroy(_Where._Ptr, _Oldlast);

				_TRY_BEGIN
				_Ucopy(_First, _Last, _Where._Ptr);
				_CATCH_ALL
				// glue the broken pieces back together

					_TRY_BEGIN
					_Umove(_Relocated, this->_Mylast(), _Where._Ptr);
					_CATCH_ALL
					// vaporize the detached piece
					_Orphan_range(_Where._Ptr, _Oldlast);
					_Destroy(_Relocated, this->_Mylast());
					this->_Mylast() = _Where._Ptr;
					_RERAISE;
					_CATCH_END

					_Destroy(_Relocated, this->_Mylast());
					this->_Mylast() = _Oldlast;
				_RERAISE;
				_CATCH_END
				}

			_Orphan_range(_Where._Ptr, _Oldlast);
			}
		}

public:
	template<class _Iter>
		enable_if_t<_Is_iterator<_Iter>::value, iterator>
		insert(const_iterator _Where, _Iter _First, _Iter _Last)
		{	// insert [_First, _Last) at _Where
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Where._Getcont() != _STD addressof(this->_Get_data())
			|| _Where._Ptr < this->_Myfirst()
			|| this->_Mylast() < _Where._Ptr)
			{
			_DEBUG_ERROR("vector insert iterator outside range");
			}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		_DEBUG_RANGE(_First, _Last);

		const size_type _Whereoff = _Where._Ptr - this->_Myfirst();
		_Insert_range(_Where, _Unchecked(_First), _Unchecked(_Last), _Iter_cat_t<_Iter>{});
		return (begin() + _Whereoff);
		}

	iterator insert(const_iterator _Where, initializer_list<_Ty> _Ilist)
		{	// insert initializer_list at _Where
		return (insert(_Where, _Ilist.begin(), _Ilist.end()));
		}

	void assign(_CRT_GUARDOVERFLOW const size_type _Newsize, const _Ty& _Val)
		{	// assign _Newsize * _Val
		this->_Orphan_all();

		const size_type _Oldsize = size();
		const size_type _Oldcapacity = capacity();

		if (_Newsize > _Oldcapacity)
			{	// reallocate
			if (_Newsize > max_size())
				{
				_Xlength();
				}

			const size_type _Newcapacity = _Calculate_growth(_Newsize);

			if (this->_Myfirst() != pointer())
				{	// destroy and deallocate old array
				_Destroy(this->_Myfirst(), this->_Mylast());
				this->_Getal().deallocate(this->_Myfirst(), _Oldcapacity);
				}

			_Buy(_Newcapacity);

			this->_Mylast() = _Ufill(this->_Myfirst(), _Newsize, _Val);
			}
		else if (_Newsize > _Oldsize)
			{
			_Fill_unchecked(this->_Myfirst(), this->_Mylast(), _Val);
			this->_Mylast() = _Ufill(this->_Mylast(), _Newsize - _Oldsize, _Val);
			}
		else
			{
			const pointer _Newlast = this->_Myfirst() + _Newsize;
			_Fill_unchecked(this->_Myfirst(), _Newlast, _Val);
			_Destroy(_Newlast, this->_Mylast());
			this->_Mylast() = _Newlast;
			}
		}

private:
	template<class _Iter>
		void _Assign_range(_Iter _First, _Iter _Last, input_iterator_tag)
		{	// assign [_First, _Last), input iterators
		this->_Orphan_all();

		pointer _Next = this->_Myfirst();

		for (; _First != _Last && _Next != this->_Mylast(); ++_First, (void)++_Next)
			{
			*_Next = *_First;
			}

		// Code size optimization: we've exhausted only the source, only the dest, or both.
		// If we've exhausted only the source: we Trim, then Append does nothing.
		// If we've exhausted only the dest: Trim does nothing, then we Append.
		// If we've exhausted both: Trim does nothing, then Append does nothing.

		// Trim.
		_Destroy(_Next, this->_Mylast());
		this->_Mylast() = _Next;

		// Append.
		for (; _First != _Last; ++_First)
			{
			emplace_back(*_First);	// performance note: emplace_back()'s strong guarantee is unnecessary here
			}
		}

	template<class _Iter>
		void _Assign_range(_Iter _First, _Iter _Last, forward_iterator_tag)
		{	// assign [_First, _Last), forward iterators
		const size_type _Newsize = _STD distance(_First, _Last);

		this->_Orphan_all();

		const size_type _Oldsize = size();
		const size_type _Oldcapacity = capacity();

		if (_Newsize > _Oldcapacity)
			{	// reallocate
			if (_Newsize > max_size())
				{
				_Xlength();
				}

			const size_type _Newcapacity = _Calculate_growth(_Newsize);

			if (this->_Myfirst() != pointer())
				{	// destroy and deallocate old array
				_Destroy(this->_Myfirst(), this->_Mylast());
				this->_Getal().deallocate(this->_Myfirst(), _Oldcapacity);
				}

			_Buy(_Newcapacity);

			this->_Mylast() = _Ucopy(_First, _Last, this->_Myfirst());
			}
		else if (_Newsize > _Oldsize)
			{
			const _Iter _Mid = _STD next(_First, _Oldsize);	// performance note: traversing [_First, _Mid) twice
			_Copy_unchecked(_First, _Mid, this->_Myfirst());
			this->_Mylast() = _Ucopy(_Mid, _Last, this->_Mylast());
			}
		else
			{
			const pointer _Newlast = this->_Myfirst() + _Newsize;
			_Copy_unchecked(_First, _Last, this->_Myfirst());
			_Destroy(_Newlast, this->_Mylast());
			this->_Mylast() = _Newlast;
			}
		}

public:
	template<class _Iter>
		enable_if_t<_Is_iterator<_Iter>::value, void>
		assign(_Iter _First, _Iter _Last)
		{	// assign [_First, _Last)
		_DEBUG_RANGE(_First, _Last);
		_Assign_range(_Unchecked(_First), _Unchecked(_Last), _Iter_cat_t<_Iter>{});
		}

	void assign(initializer_list<_Ty> _Ilist)
		{	// assign initializer_list
		_Assign_range(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{});
		}

	vector& operator=(const vector& _Right)
		{	// assign _Right
		if (this != _STD addressof(_Right))
			{	// different, assign it
#pragma warning(push)
#pragma warning(disable: 4127)	// conditional expression is constant
			if (_Alty::propagate_on_container_copy_assignment::value && this->_Getal() != _Right._Getal())
				{	// reload array
				_Tidy();
				}
#pragma warning(pop)

			this->_Copy_alloc(_Right._Getal());

			assign(_Right._Myfirst(), _Right._Mylast());
			}

		return (*this);
		}

	vector& operator=(initializer_list<_Ty> _Ilist)
		{	// assign initializer_list
		_Assign_range(_Ilist.begin(), _Ilist.end(), random_access_iterator_tag{});
		return (*this);
		}

private:
	template<class _Lambda>
		void _Resize(const size_type _Newsize, _Lambda _Udefault_or_fill)
		{	// trim or append elements, provide strong guarantee
		const size_type _Oldsize = size();
		const size_type _Oldcapacity = capacity();

		if (_Newsize > _Oldcapacity)
			{	// reallocate
			if (_Newsize > max_size())
				{
				_Xlength();
				}

			const size_type _Newcapacity = _Calculate_growth(_Newsize);

			const pointer _Newvec = this->_Getal().allocate(_Newcapacity);
			const pointer _Appended_first = _Newvec + _Oldsize;
			pointer _Appended_last = _Appended_first;

			_TRY_BEGIN
			_Appended_last = _Udefault_or_fill(_Appended_first, _Newsize - _Oldsize);
			_Umove_if_noexcept(this->_Myfirst(), this->_Mylast(), _Newvec);
			_CATCH_ALL
			_Destroy(_Appended_first, _Appended_last);
			this->_Getal().deallocate(_Newvec, _Newcapacity);
			_RERAISE;
			_CATCH_END

			_Change_array(_Newvec, _Newsize, _Newcapacity);
			}
		else if (_Newsize > _Oldsize)
			{	// append
			const pointer _Oldlast = this->_Mylast();
			this->_Mylast() = _Udefault_or_fill(_Oldlast, _Newsize - _Oldsize);
			_Orphan_range(_Oldlast, _Oldlast);
			}
		else if (_Newsize == _Oldsize)
			{	// nothing to do, avoid invalidating iterators
			}
		else
			{	// trim
			const pointer _Newlast = this->_Myfirst() + _Newsize;
			_Orphan_range(_Newlast, this->_Mylast());
			_Destroy(_Newlast, this->_Mylast());
			this->_Mylast() = _Newlast;
			}
		}

public:
	void resize(_CRT_GUARDOVERFLOW const size_type _Newsize)
		{	// trim or append value-initialized elements, provide strong guarantee
		auto _Lambda_default = [this](pointer _Dest, const size_type _Count)
			{
			return (_Udefault(_Dest, _Count));
			};

		_Resize(_Newsize, _Lambda_default);
		}

	void resize(_CRT_GUARDOVERFLOW const size_type _Newsize, const _Ty& _Val)
		{	// trim or append copies of _Val, provide strong guarantee
		auto _Lambda_fill = [this, &_Val](pointer _Dest, const size_type _Count)
			{
			return (_Ufill(_Dest, _Count, _Val));
			};

		_Resize(_Newsize, _Lambda_fill);
		}

private:
	void _Reallocate_exactly(const size_type _Newcapacity)
		{	// set capacity to _Newcapacity (without geometric growth), provide strong guarantee
		const size_type _Size = size();

		const pointer _Newvec = this->_Getal().allocate(_Newcapacity);

		_TRY_BEGIN
		_Umove_if_noexcept(this->_Myfirst(), this->_Mylast(), _Newvec);
		_CATCH_ALL
		this->_Getal().deallocate(_Newvec, _Newcapacity);
		_RERAISE;
		_CATCH_END

		_Change_array(_Newvec, _Size, _Newcapacity);
		}

public:
	void reserve(_CRT_GUARDOVERFLOW const size_type _Newcapacity)
		{	// increase capacity to _Newcapacity (without geometric growth), provide strong guarantee
		if (_Newcapacity > capacity())
			{	// something to do (reserve() never shrinks)
			if (_Newcapacity > max_size())
				{
				_Xlength();
				}

			_Reallocate_exactly(_Newcapacity);
			}
		}

	void shrink_to_fit()
		{	// reduce capacity to size, provide strong guarantee
		if (_Has_unused_capacity())
			{	// something to do
			if (empty())
				{
				_Tidy();
				}
			else
				{
				_Reallocate_exactly(size());
				}
			}
		}

	void pop_back()
		{	// erase element at end
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (empty())
			{
			_DEBUG_ERROR("vector empty before pop");
			}

		_Orphan_range(this->_Mylast() - 1, this->_Mylast());
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		this->_Getal().destroy(_Unfancy(this->_Mylast() - 1));
		--this->_Mylast();
		}

	iterator erase(const_iterator _Where)
		{	// erase element at _Where
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Where._Getcont() != _STD addressof(this->_Get_data())
			|| _Where._Ptr < this->_Myfirst()
			|| this->_Mylast() <= _Where._Ptr)
			{
			_DEBUG_ERROR("vector erase iterator outside range");
			}

		_Orphan_range(_Where._Ptr, this->_Mylast());
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		_Move_unchecked(_Where._Ptr + 1, this->_Mylast(), _Where._Ptr);
		this->_Getal().destroy(_Unfancy(this->_Mylast() - 1));
		--this->_Mylast();
		return (iterator(_Where._Ptr, _STD addressof(this->_Get_data())));
		}

	iterator erase(const_iterator _First, const_iterator _Last)
		{	// erase [_First, _Last)
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_First._Getcont() != _STD addressof(this->_Get_data())
			|| _Last._Getcont() != _STD addressof(this->_Get_data())
			|| _First._Ptr < this->_Myfirst()
			|| _Last._Ptr < _First._Ptr
			|| this->_Mylast() < _Last._Ptr)
			{
			_DEBUG_ERROR("vector erase iterator outside range");
			}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		if (_First._Ptr != _Last._Ptr)
			{	// something to do, invalidate iterators
			_Orphan_range(_First._Ptr, this->_Mylast());
			const pointer _Newlast = _Move_unchecked(_Last._Ptr, this->_Mylast(), _First._Ptr);
			_Destroy(_Newlast, this->_Mylast());
			this->_Mylast() = _Newlast;
			}

		return (iterator(_First._Ptr, _STD addressof(this->_Get_data())));
		}

	void clear() _NOEXCEPT
		{	// erase all
		this->_Orphan_all();
		_Destroy(this->_Myfirst(), this->_Mylast());
		this->_Mylast() = this->_Myfirst();
		}

	void swap(vector& _Right)
		_NOEXCEPT_OP(_Alty::propagate_on_container_swap::value || _Alty::is_always_equal::value)
		{	// exchange contents with _Right
		if (this != _STD addressof(_Right))
			{	// (maybe) swap allocators, swap control information
			_Pocs(this->_Getal(), _Right._Getal());
			this->_Swap_all(_Right);
			_Swap_adl(this->_Myfirst(), _Right._Myfirst());
			_Swap_adl(this->_Mylast(), _Right._Mylast());
			_Swap_adl(this->_Myend(), _Right._Myend());
			}
		}

	_Ty * data() _NOEXCEPT
		{	// return address of first element
		return (_Unfancy_maybe_null(this->_Myfirst()));
		}

	const _Ty * data() const _NOEXCEPT
		{	// return address of first element
		return (_Unfancy_maybe_null(this->_Myfirst()));
		}

	iterator begin() _NOEXCEPT
		{	// return iterator for beginning of mutable sequence
		return (iterator(this->_Myfirst(), _STD addressof(this->_Get_data())));
		}

	const_iterator begin() const _NOEXCEPT
		{	// return iterator for beginning of nonmutable sequence
		return (const_iterator(this->_Myfirst(), _STD addressof(this->_Get_data())));
		}

	iterator end() _NOEXCEPT
		{	// return iterator for end of mutable sequence
		return (iterator(this->_Mylast(), _STD addressof(this->_Get_data())));
		}

	const_iterator end() const _NOEXCEPT
		{	// return iterator for end of nonmutable sequence
		return (const_iterator(this->_Mylast(), _STD addressof(this->_Get_data())));
		}

	reverse_iterator rbegin() _NOEXCEPT
		{	// return iterator for beginning of reversed mutable sequence
		return (reverse_iterator(end()));
		}

	const_reverse_iterator rbegin() const _NOEXCEPT
		{	// return iterator for beginning of reversed nonmutable sequence
		return (const_reverse_iterator(end()));
		}

	reverse_iterator rend() _NOEXCEPT
		{	// return iterator for end of reversed mutable sequence
		return (reverse_iterator(begin()));
		}

	const_reverse_iterator rend() const _NOEXCEPT
		{	// return iterator for end of reversed nonmutable sequence
		return (const_reverse_iterator(begin()));
		}

	const_iterator cbegin() const _NOEXCEPT
		{	// return iterator for beginning of nonmutable sequence
		return (begin());
		}

	const_iterator cend() const _NOEXCEPT
		{	// return iterator for end of nonmutable sequence
		return (end());
		}

	const_reverse_iterator crbegin() const _NOEXCEPT
		{	// return iterator for beginning of reversed nonmutable sequence
		return (rbegin());
		}

	const_reverse_iterator crend() const _NOEXCEPT
		{	// return iterator for end of reversed nonmutable sequence
		return (rend());
		}

	bool empty() const _NOEXCEPT
		{	// test if sequence is empty
		return (this->_Myfirst() == this->_Mylast());
		}

	size_type size() const _NOEXCEPT
		{	// return length of sequence
		return (this->_Mylast() - this->_Myfirst());
		}

	size_type max_size() const _NOEXCEPT
		{	// return maximum possible length of sequence
		return (this->_Getal().max_size());
		}

	size_type capacity() const _NOEXCEPT
		{	// return current length of allocated storage
		return (this->_Myend() - this->_Myfirst());
		}

private:
	size_type _Unused_capacity() const _NOEXCEPT
		{	// micro-optimization for capacity() - size()
		return (this->_Myend() - this->_Mylast());
		}

	bool _Has_unused_capacity() const _NOEXCEPT
		{	// micro-optimization for capacity() != size()
		return (this->_Myend() != this->_Mylast());
		}

public:
	_Ty& operator[](const size_type _Pos)
		{	// subscript mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (size() <= _Pos)
			{	// report error
			_DEBUG_ERROR("vector subscript out of range");
			}
 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (this->_Myfirst()[_Pos]);
		}

	const _Ty& operator[](const size_type _Pos) const
		{	// subscript nonmutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (size() <= _Pos)
			{	// report error
			_DEBUG_ERROR("vector subscript out of range");
			}
 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (this->_Myfirst()[_Pos]);
		}

	_Ty& at(const size_type _Pos)
		{	// subscript mutable sequence with checking
		if (size() <= _Pos)
			{
			_Xrange();
			}

		return (this->_Myfirst()[_Pos]);
		}

	const _Ty& at(const size_type _Pos) const
		{	// subscript nonmutable sequence with checking
		if (size() <= _Pos)
			{
			_Xrange();
			}

		return (this->_Myfirst()[_Pos]);
		}

	_Ty& front()
		{	// return first element of mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (empty())
			{	// report error
			_DEBUG_ERROR("front() called on empty vector");
			}
 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(!empty());
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (*this->_Myfirst());
		}

	const _Ty& front() const
		{	// return first element of nonmutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (empty())
			{	// report error
			_DEBUG_ERROR("front() called on empty vector");
			}
 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(!empty());
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (*this->_Myfirst());
		}

	_Ty& back()
		{	// return last element of mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (empty())
			{	// report error
			_DEBUG_ERROR("back() called on empty vector");
			}
 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(!empty());
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (this->_Mylast()[-1]);
		}

	const _Ty& back() const
		{	// return last element of nonmutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (empty())
			{	// report error
			_DEBUG_ERROR("back() called on empty vector");
			}
 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(!empty());
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (this->_Mylast()[-1]);
		}

	_Alloc get_allocator() const _NOEXCEPT
		{	// return allocator object for values
		_Alloc _Ret(this->_Getal());
		return (_Ret);
		}

private:
	pointer _Udefault(pointer _Dest, const size_type _Count)
		{	// fill raw _Dest with _Count value-initialized objects, using allocator
		return (_Uninitialized_default_fill_n(_Dest, _Count, this->_Getal()));
		}

	pointer _Ufill(pointer _Dest, const size_type _Count, const _Ty& _Val)
		{	// fill raw _Dest with _Count copies of _Val, using allocator
		return (_Uninitialized_fill_n(_Dest, _Count, _Val, this->_Getal()));
		}

	template<class _Iter>
		pointer _Ucopy(_Iter _First, _Iter _Last, pointer _Dest)
		{	// copy [_First, _Last) to raw _Dest, using allocator
		return (_Uninitialized_copy(_First, _Last, _Dest, this->_Getal()));
		}

	pointer _Umove(pointer _First, pointer _Last, pointer _Dest)
		{	// move [_First, _Last) to raw _Dest, using allocator
		return (_Uninitialized_move(_First, _Last, _Dest, this->_Getal()));
		}

	void _Umove_if_noexcept1(pointer _First, pointer _Last, pointer _Dest, true_type)
		{	// move [_First, _Last) to raw _Dest, using allocator
		_Uninitialized_move(_First, _Last, _Dest, this->_Getal());
		}

	void _Umove_if_noexcept1(pointer _First, pointer _Last, pointer _Dest, false_type)
		{	// copy [_First, _Last) to raw _Dest, using allocator
		_Uninitialized_copy(_First, _Last, _Dest, this->_Getal());
		}

	void _Umove_if_noexcept(pointer _First, pointer _Last, pointer _Dest)
		{	// move_if_noexcept [_First, _Last) to raw _Dest, using allocator
		_Umove_if_noexcept1(_First, _Last, _Dest,
			_Disjunction_t<is_nothrow_move_constructible<_Ty>, negation<is_copy_constructible<_Ty>>>{});
		}

	void _Destroy(pointer _First, pointer _Last)
		{	// destroy [_First, _Last) using allocator
		_Destroy_range(_First, _Last, this->_Getal());
		}

	size_type _Calculate_growth(const size_type _Newsize) const
		{	// given _Oldcapacity and _Newsize, calculate geometric growth
		const size_type _Oldcapacity = capacity();

		if (_Oldcapacity > max_size() - _Oldcapacity / 2)
			{
			return (_Newsize);	// geometric growth would overflow
			}

		const size_type _Geometric = _Oldcapacity + _Oldcapacity / 2;

		if (_Geometric < _Newsize)
			{
			return (_Newsize);	// geometric growth would be insufficient
			}

		return (_Geometric);	// geometric growth is sufficient
		}

	bool _Buy(const size_type _Newcapacity)
		{	// allocate array with _Newcapacity elements
		this->_Myfirst() = pointer();
		this->_Mylast() = pointer();
		this->_Myend() = pointer();

		if (_Newcapacity == 0)
			{
			return (false);
			}

		if (_Newcapacity > max_size())
			{
			_Xlength();
			}

		this->_Myfirst() = this->_Getal().allocate(_Newcapacity);
		this->_Mylast() = this->_Myfirst();
		this->_Myend() = this->_Myfirst() + _Newcapacity;

		return (true);
		}

	void _Change_array(const pointer _Newvec, const size_type _Newsize, const size_type _Newcapacity)
		{	// orphan all iterators, discard old array, acquire new array
		this->_Orphan_all();

		if (this->_Myfirst() != pointer())
			{	// destroy and deallocate old array
			_Destroy(this->_Myfirst(), this->_Mylast());
			this->_Getal().deallocate(this->_Myfirst(), this->_Myend() - this->_Myfirst());
			}

		this->_Myfirst() = _Newvec;
		this->_Mylast() = _Newvec + _Newsize;
		this->_Myend() = _Newvec + _Newcapacity;
		}

	void _Tidy()
		{	// free all storage
		this->_Orphan_all();

		if (this->_Myfirst() != pointer())
			{	// destroy and deallocate old array
			_Destroy(this->_Myfirst(), this->_Mylast());
			this->_Getal().deallocate(this->_Myfirst(), this->_Myend() - this->_Myfirst());

			this->_Myfirst() = pointer();
			this->_Mylast() = pointer();
			this->_Myend() = pointer();
			}
		}

	[[noreturn]] static void _Xlength()
		{	// report a length_error
		_Xlength_error("vector<T> too long");
		}

	[[noreturn]] static void _Xrange()
		{	// report an out_of_range error
		_Xout_of_range("invalid vector<T> subscript");
		}

 #if _ITERATOR_DEBUG_LEVEL == 2
	void _Orphan_range(pointer _First, pointer _Last) const
		{	// orphan iterators within specified (inclusive) range
		_Lockit _Lock(_LOCK_DEBUG);

		const_iterator ** _Pnext = reinterpret_cast<const_iterator **>(this->_Getpfirst());

		if (_Pnext)
			{
			while (*_Pnext)
				{
				if ((*_Pnext)->_Ptr < _First || _Last < (*_Pnext)->_Ptr)
					{	// skip the iterator
					_Pnext = reinterpret_cast<const_iterator **>((*_Pnext)->_Getpnext());
					}
				else
					{	// orphan the iterator
					(*_Pnext)->_Clrcont();
					*_Pnext = *reinterpret_cast<const_iterator **>((*_Pnext)->_Getpnext());
					}
				}
			}
		}
 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
	void _Orphan_range(pointer, pointer) const
		{	// orphan iterators within specified (inclusive) range
		}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
	};

		// vector TEMPLATE OPERATORS
template<class _Ty,
	class _Alloc> inline
	void swap(vector<_Ty, _Alloc>& _Left, vector<_Ty, _Alloc>& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
	{	// swap _Left and _Right vectors
	_Left.swap(_Right);
	}

template<class _Ty,
	class _Alloc> inline
	bool operator==(const vector<_Ty, _Alloc>& _Left,
		const vector<_Ty, _Alloc>& _Right)
	{	// test for vector equality
	return (_Left.size() == _Right.size()
		&& _STD equal(_Left.begin(), _Left.end(), _Right.begin()));
	}

template<class _Ty,
	class _Alloc> inline
	bool operator!=(const vector<_Ty, _Alloc>& _Left,
		const vector<_Ty, _Alloc>& _Right)
	{	// test for vector inequality
	return (!(_Left == _Right));
	}

template<class _Ty,
	class _Alloc> inline
	bool operator<(const vector<_Ty, _Alloc>& _Left,
		const vector<_Ty, _Alloc>& _Right)
	{	// test if _Left < _Right for vectors
	return (_STD lexicographical_compare(_Left.begin(), _Left.end(),
		_Right.begin(), _Right.end()));
	}

template<class _Ty,
	class _Alloc> inline
	bool operator>(const vector<_Ty, _Alloc>& _Left,
		const vector<_Ty, _Alloc>& _Right)
	{	// test if _Left > _Right for vectors
	return (_Right < _Left);
	}

template<class _Ty,
	class _Alloc> inline
	bool operator<=(const vector<_Ty, _Alloc>& _Left,
		const vector<_Ty, _Alloc>& _Right)
	{	// test if _Left <= _Right for vectors
	return (!(_Right < _Left));
	}

template<class _Ty,
	class _Alloc> inline
	bool operator>=(const vector<_Ty, _Alloc>& _Left,
		const vector<_Ty, _Alloc>& _Right)
	{	// test if _Left >= _Right for vectors
	return (!(_Left < _Right));
	}

//
// TEMPLATE CLASS vector<bool, Alloc> AND FRIENDS
//
typedef unsigned int _Vbase;	// word type for vector<bool> representation
const int _VBITS = 8 * sizeof (_Vbase);	// at least CHAR_BITS bits per word

		// CLASS _Vb_iter_base
template<class _Alloc>
	class _Vb_iter_base
		: public _Iterator012<random_access_iterator_tag,
			bool,
			typename _Alloc::difference_type,
			bool *,
			bool,
			_Iterator_base>
	{	// store information common to reference and iterators
public:
	typedef typename _Alloc::size_type _Sizet;
	typedef vector<bool, _Alloc> _Mycont;

	_Vb_iter_base()
		: _Myptr(0), _Myoff(0)
		{	// construct with null pointer
		}

	_Vb_iter_base(const _Vbase *_Ptr, _Sizet _Off,
		const _Container_base *_Mypvbool)
		: _Myptr(_Ptr), _Myoff(_Off)
		{	// construct with offset and pointer
		this->_Adopt(_Mypvbool);
		}

	void _Advance(_Sizet _Off)
		{	// advance iterator by _Off
		_Myoff += _Off;
		_Myptr += _Myoff / _VBITS;
		_Myoff %= _VBITS;
		}

	int _Valid(_Sizet _Inc) const
		{	// test for valid incremented offset
 #if _ITERATOR_DEBUG_LEVEL == 2
		const auto _Cont = static_cast<const _Mycont *>(this->_Getcont());
		_Sizet _Mysize = _Cont->_Mysize;

		_Inc += _Myoff;
		_Inc += _VBITS * (_Myptr - _Cont->_Myvec.data());
		return (_Inc < _Mysize ? -1 : _Inc == _Mysize ? 0 : +1);

 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
		(void)_Inc;
		return (-1);
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
		}

	const _Vbase *_Myptr;
	_Sizet _Myoff;
	};

		// CLASS _Vb_reference
template<class _Alloc>
	class _Vb_reference
		: public _Vb_iter_base<_Alloc>
	{	// reference to a bit within a base word
	typedef _Vb_iter_base<_Alloc> _Mybase;
	typedef _Vb_reference<_Alloc> _Mytype;

	_Vb_reference() _NOEXCEPT
		{	// construct with null pointer (private)
		}

public:
	_Vb_reference(const _Mybase& _Right)
		: _Mybase(_Right._Myptr, _Right._Myoff, _Right._Getcont())
		{	// construct with base
		}

	_Mytype& operator=(const _Mytype& _Right) _NOEXCEPT
		{	// assign _Vb_reference _Right to bit
		return (*this = bool(_Right));
		}

	_Mytype& operator=(bool _Val) _NOEXCEPT
		{	// assign _Val to bit
		if (_Val)
			*(_Vbase *)_Getptr() |= _Mask();
		else
			*(_Vbase *)_Getptr() &= (~_Mask());	// STET
		return (*this);
		}

	void flip() _NOEXCEPT
		{	// toggle the bit
		*(_Vbase *)_Getptr() ^= _Mask();
		}

	operator bool() const _NOEXCEPT
		{	// test if bit is set
		return ((*_Getptr() & _Mask()) != 0);
		}

	const _Vbase *_Getptr() const
		{	// get pointer to base word
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (this->_Getcont() == 0
			|| this->_Myptr == 0
			|| 0 <= this->_Valid(0))
			{	// report error
			_DEBUG_ERROR("vector<bool> iterator not dereferencable");
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE(this->_Getcont() != 0 && this->_Myptr != 0);
		_SCL_SECURE_VALIDATE_RANGE(this->_Valid(0) < 0);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (this->_Myptr);
		}

protected:
	_Vbase _Mask() const
		{	// convert offset to mask
		return ((_Vbase)(1) << this->_Myoff);
		}
	};

template<class _Alloc> inline
	void swap(_Vb_reference<_Alloc> _Left,
		_Vb_reference<_Alloc> _Right)
	{	// swap _Left and _Right vector<bool> elements
	bool _Val = _Left;	// NOT _STD swap
	_Left = _Right;
	_Right = _Val;
	}

		// CLASS _Vb_const_iterator
template<class _Alloc>
	class _Vb_const_iterator
		: public _Vb_iter_base<_Alloc>
	{	// iterator for nonmutable vector<bool>
public:
	typedef _Vb_iter_base<_Alloc> _Mybase;
	typedef _Vb_const_iterator<_Alloc> _Mytype;

	typedef _Vb_reference<_Alloc> _Reft;
	typedef bool const_reference;

	typedef random_access_iterator_tag iterator_category;
	typedef bool value_type;
	typedef typename _Alloc::size_type size_type;
	typedef typename _Alloc::difference_type difference_type;
	typedef const_reference *pointer;
	typedef const_reference reference;

	_Vb_const_iterator()
		{	// construct with null reference
		}

	_Vb_const_iterator(const _Vbase *_Ptr, const _Container_base *_Mypvbool)
		: _Mybase(_Ptr, 0, _Mypvbool)
		{	// construct with offset and pointer
		}

	const_reference operator*() const
		{	// return (reference to) designated object
		return (_Reft(*this));
		}

	_Mytype& operator++()
		{	// preincrement
		_Inc();
		return (*this);
		}

	_Mytype operator++(int)
		{	// postincrement
		_Mytype _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Mytype& operator--()
		{	// predecrement
		_Dec();
		return (*this);
		}

	_Mytype operator--(int)
		{	// postdecrement
		_Mytype _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Mytype& operator+=(difference_type _Off)
		{	// increment by integer
		if (_Off < 0 && this->_Myoff < 0 - (size_type)_Off)
			{	/* add negative increment */
			this->_Myoff += _Off;
			this->_Myptr -= 1 + ((size_type)(-1) - this->_Myoff) / _VBITS;
			this->_Myoff %= _VBITS;
			}
		else
			{	/* add non-negative increment */
			this->_Myoff += _Off;
			this->_Myptr += this->_Myoff / _VBITS;
			this->_Myoff %= _VBITS;
			}
		return (*this);
		}

	_Mytype operator+(difference_type _Off) const
		{	// return this + integer
		_Mytype _Tmp = *this;
		return (_Tmp += _Off);
		}

	_Mytype& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

	_Mytype operator-(difference_type _Off) const
		{	// return this - integer
		_Mytype _Tmp = *this;
		return (_Tmp -= _Off);
		}

	difference_type operator-(
		const _Mytype& _Right) const
		{	// return difference of iterators
		_Compat(_Right);
		return (_VBITS * (this->_Myptr - _Right._Myptr)
			+ (difference_type)this->_Myoff
			- (difference_type)_Right._Myoff);
		}

	const_reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}

	bool operator==(const _Mytype& _Right) const
		{	// test for iterator equality
		_Compat(_Right);
		return (this->_Myptr == _Right._Myptr
			&& this->_Myoff == _Right._Myoff);
		}

	bool operator!=(const _Mytype& _Right) const
		{	// test for iterator inequality
		return (!(*this == _Right));
		}

	bool operator<(const _Mytype& _Right) const
		{	// test if this < _Right
		_Compat(_Right);
		return (this->_Myptr < _Right._Myptr
			|| (this->_Myptr == _Right._Myptr
				&& this->_Myoff < _Right._Myoff));
		}

	bool operator>(const _Mytype& _Right) const
		{	// test if this > _Right
		return (_Right < *this);
		}

	bool operator<=(const _Mytype& _Right) const
		{	// test if this <= _Right
		return (!(_Right < *this));
		}

	bool operator>=(const _Mytype& _Right) const
		{	// test if this >= _Right
		return (!(*this < _Right));
		}

 #if _ITERATOR_DEBUG_LEVEL == 2
	void _Compat(const _Mytype& _Right) const
		{	// test for compatible iterator pair
		if (this->_Getcont() != _Right._Getcont())
			{
			_DEBUG_ERROR("vector<bool> iterators incompatible");
			}
		}

 #elif _ITERATOR_DEBUG_LEVEL == 1
	void _Compat(const _Mytype& _Right) const
		{	// test for compatible iterator pair
		_SCL_SECURE_VALIDATE_RANGE(this->_Getcont() == _Right._Getcont());
		}

 #else /* _ITERATOR_DEBUG_LEVEL == 0 */
	void _Compat(const _Mytype&) const
		{	// test for compatible iterator pair
		}
 #endif /* _ITERATOR_DEBUG_LEVEL */

	void _Dec()
		{	// decrement bit position
		if (this->_Myoff != 0)
			--this->_Myoff;
		else
			{	// move to previous word
 #if _ITERATOR_DEBUG_LEVEL == 2
			if (this->_Getcont() == 0 || 0 < this->_Valid((size_type)-1))
				{	// report error
				_DEBUG_ERROR("vector<bool> iterator not decrementable");
				}

 #elif _ITERATOR_DEBUG_LEVEL == 1
			_SCL_SECURE_VALIDATE(this->_Getcont() != 0);
			_SCL_SECURE_VALIDATE_RANGE(this->_Valid((size_type)-1) <= 0);
 #endif /* _ITERATOR_DEBUG_LEVEL */

			this->_Myoff = _VBITS - 1;
			--this->_Myptr;
			}
		}

	void _Inc()
		{	// increment bit position
		if (this->_Myoff < _VBITS - 1)
			++this->_Myoff;
		else
			{	// move to next word
 #if _ITERATOR_DEBUG_LEVEL == 2
			if (this->_Getcont() == 0 || 0 < this->_Valid(1))
				{	// report error
				_DEBUG_ERROR("vector<bool> iterator not incrementable");
				}

 #elif _ITERATOR_DEBUG_LEVEL == 1
			_SCL_SECURE_VALIDATE(this->_Getcont() != 0);
			_SCL_SECURE_VALIDATE_RANGE(this->_Valid(1) <= 0);
 #endif /* _ITERATOR_DEBUG_LEVEL */

			this->_Myoff = 0;
			++this->_Myptr;
			}
		}
	};

template<class _Alloc> inline
	_Vb_const_iterator<_Alloc> operator+(
		typename _Alloc::difference_type _Off,
		_Vb_const_iterator<_Alloc> _Right)
		{	// return _Right + integer
		return (_Right += _Off);
		}

template<class _Alloc>
	struct _Is_checked_helper<_Vb_const_iterator<_Alloc> >
		: public true_type
	{	// mark _Vb_const_iterator as checked
	};

	// CLASS _Vb_iterator
template<class _Alloc>
	class _Vb_iterator
		: public _Vb_const_iterator<_Alloc>
	{	// iterator for mutable vector<bool>
public:
	typedef _Vb_const_iterator<_Alloc> _Mybase;
	typedef _Vb_iterator<_Alloc> _Mytype;

	typedef _Vb_reference<_Alloc> _Reft;
	typedef bool const_reference;

	typedef random_access_iterator_tag iterator_category;
	typedef bool value_type;
	typedef typename _Alloc::size_type size_type;
	typedef typename _Alloc::difference_type difference_type;
	typedef _Reft *pointer;
	typedef _Reft reference;

	_Vb_iterator()
		{	// construct with null reference
		}

	_Vb_iterator(_Vbase *_Ptr, _Container_base *_Mypvbool)
		: _Mybase(_Ptr, _Mypvbool)
		{	// construct with offset and pointer
		}

	reference operator*() const
		{	// return (reference to) designated object
		return (_Reft(*this));
		}

	_Mytype& operator++()
		{	// preincrement
		++*(_Mybase *)this;
		return (*this);
		}

	_Mytype operator++(int)
		{	// postincrement
		_Mytype _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Mytype& operator--()
		{	// predecrement
		--*(_Mybase *)this;
		return (*this);
		}

	_Mytype operator--(int)
		{	// postdecrement
		_Mytype _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Mytype& operator+=(difference_type _Off)
		{	// increment by integer
		*(_Mybase *)this += _Off;
		return (*this);
		}

	_Mytype operator+(difference_type _Off) const
		{	// return this + integer
		_Mytype _Tmp = *this;
		return (_Tmp += _Off);
		}

	_Mytype& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

	_Mytype operator-(difference_type _Off) const
		{	// return this - integer
		_Mytype _Tmp = *this;
		return (_Tmp -= _Off);
		}

	difference_type operator-(const _Mybase& _Right) const
		{	// return difference of iterators
		return (*(_Mybase *)this - _Right);
		}

	reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}
	};

template<class _Alloc> inline
	_Vb_iterator<_Alloc> operator+(typename _Alloc::difference_type _Off,
		_Vb_iterator<_Alloc> _Right)
		{	// return _Right + integer
		return (_Right += _Off);
		}

template<class _Alloc>
	struct _Is_checked_helper<_Vb_iterator<_Alloc> >
		: public true_type
	{	// mark _Vb_iterator as checked
	};

		// TEMPLATE CLASS _Vb_val
template<class _Alloc>
	class _Vb_val
		: public _Container_base
	{	// base class for vector<bool> to hold data
public:
	typedef vector<_Vbase, _Alloc> _Vectype;
	typedef typename _Vector_alloc<_Vec_base_types<_Vbase, _Alloc> >::_Alty _Alty;
	typedef typename _Alty::size_type size_type;

	_Vb_val(size_type _Count, const bool& _Val)
		: _Myvec(_Nw(_Count), (_Vbase) (_Val ? -1 : 0))
		{	// construct _Count * _Val elements
		_Alloc_proxy();
		_Mysize = 0;
		}

	_Vb_val(size_type _Count, const bool& _Val, const _Alloc& _Al)
		: _Myvec(_Nw(_Count), (_Vbase)(_Val ? -1 : 0), _Al)
		{	// construct _Count * _Val elements with allocator _Al
		_Alloc_proxy();
		_Mysize = 0;
		}

	_Vb_val(const _Vb_val& _Right)
		: _Myvec(_Right._Myvec),
			_Mysize(_Right._Mysize)
		{	// copy construct
		_Alloc_proxy();
		}

	_Vb_val(const _Vb_val& _Right, const _Alloc& _Al)
		: _Myvec(_Right._Myvec, _Al),
			_Mysize(_Right._Mysize)
		{	// copy construct, allocator
		_Alloc_proxy();
		}

	_Vb_val(_Vb_val&& _Right)
		: _Myvec(_STD forward<_Vectype>(_Right._Myvec)),
			_Mysize(_Right._Mysize)
		{	// move construct
		_Right._Mysize = 0;
		_Alloc_proxy();
		}

	_Vb_val(_Vb_val&& _Right, const _Alloc& _Al)
		: _Myvec(_STD forward<_Vectype>(_Right._Myvec), _Al),
			_Mysize(_Right._Mysize)
		{	// move construct, allocator
		_Right._Mysize = 0;
		_Alloc_proxy();
		}

	~_Vb_val() _NOEXCEPT
		{	// destroy proxy
		_Free_proxy();
		}

 #if _ITERATOR_DEBUG_LEVEL == 0
	void _Alloc_proxy()
		{	// do nothing
		}

	void _Free_proxy()
		{	// do nothing
		}

 #else /* _ITERATOR_DEBUG_LEVEL == 0 */
	void _Alloc_proxy()
		{	// allocate a proxy
		typename _Alty::template rebind<_Container_proxy>::other
			_Alproxy(_Myvec._Getal());
		this->_Myproxy = _Unfancy(_Alproxy.allocate(1));
		_Alproxy.construct(this->_Myproxy, _Container_proxy());
		this->_Myproxy->_Mycont = this;
		}

	void _Free_proxy()
		{	// destroy proxy
		typename _Alty::template rebind<_Container_proxy>::other
			_Alproxy(_Myvec._Getal());
		this->_Orphan_all();
		_Alproxy.destroy(this->_Myproxy);
		_Alproxy.deallocate(_Alproxy.address(*this->_Myproxy), 1);
		this->_Myproxy = 0;
		}
 #endif /* _ITERATOR_DEBUG_LEVEL == 0 */

	static size_type _Nw(size_type _Count)
		{	// return number of base words from number of bits
		return ((_Count + _VBITS - 1) / _VBITS);
		}

	_Vectype _Myvec;	// base vector of words
	typename _Alty::size_type _Mysize;	// current length of sequence
	};

		// CLASS vector<bool>

template<class _Alloc>
	class vector<bool, _Alloc>
		: public _Vb_val<_Alloc>
	{	// varying size array of bits
public:
	typedef vector<bool, _Alloc> _Myt;
	typedef _Vb_val<_Alloc> _Mybase;
	typedef typename _Mybase::_Alty _Alty;
	typedef typename _Mybase::_Vectype _Vectype;

	typedef typename _Alty::size_type size_type;
	typedef typename _Alty::difference_type difference_type;
	typedef bool _Ty;
	typedef _Alloc allocator_type;

	typedef _Vb_reference<_Alty> reference;
	typedef bool const_reference;
	typedef bool value_type;

	typedef reference _Reft;
	typedef _Vb_const_iterator<_Alty> const_iterator;
	typedef _Vb_iterator<_Alty> iterator;

	typedef iterator pointer;
	typedef const_iterator const_pointer;
	typedef _STD reverse_iterator<iterator> reverse_iterator;
	typedef _STD reverse_iterator<const_iterator> const_reverse_iterator;

	static const int _VBITS = _STD _VBITS;
	enum {_EEN_VBITS = _VBITS};	// helper for expression evaluator

	vector() _NOEXCEPT_OP(is_nothrow_default_constructible<_Alloc>::value)
		: _Mybase(0, false)
		{	// construct empty vector
		}

	explicit vector(const _Alloc& _Al) _NOEXCEPT
		: _Mybase(0, false, _Al)
		{	// construct empty vector, allocator
		}

	explicit vector(_CRT_GUARDOVERFLOW size_type _Count, const _Alloc& _Al = _Alloc())
		: _Mybase(_Count, false, _Al)
		{	// construct from _Count * false, optional allocator
		_Trim(_Count);
		}

	vector(_CRT_GUARDOVERFLOW size_type _Count, const bool& _Val, const _Alloc& _Al = _Alloc())
		: _Mybase(_Count, _Val, _Al)
		{	// construct from _Count * _Val, optional allocator
		_Trim(_Count);
		}

	vector(const _Myt& _Right)
		: _Mybase(_Right)
		{	// construct by copying _Right
		}

	vector(const _Myt& _Right, const _Alloc& _Al)
		: _Mybase(_Right, _Al)
		{	// construct by copying _Right, allocator
		}

	template<class _Iter,
		class = enable_if_t<_Is_iterator<_Iter>::value>>
		vector(_Iter _First, _Iter _Last, const _Alloc& _Al = _Alloc())
		: _Mybase(0, false, _Al)
		{	// construct from [_First, _Last), optional allocator
		_BConstruct(_First, _Last);
		}

	template<class _Iter>
		void _BConstruct(_Iter _First, _Iter _Last)
		{	// initialize from [_First, _Last), input iterators
		insert(begin(), _First, _Last);
		}

	vector(_Myt&& _Right)
		: _Mybase(_STD move(_Right))
		{	// move construct by moving _Right
		this->_Swap_all(_Right);
		}

	vector(_Myt&& _Right, const _Alloc& _Al)
		: _Mybase(_STD move(_Right), _Al)
		{	// move construct by moving _Right, allocator
		if (this->_Myvec._Getal() == _Right._Myvec._Getal())
			{
			this->_Swap_all(_Right);
			}
		}

	_Myt& operator=(_Myt&& _Right)
		{	// assign by moving _Right
		if (this != _STD addressof(_Right))
			{	// different, assign it
			clear();

			const bool _Reload = _Alty::propagate_on_container_move_assignment::value
				&& this->_Myvec._Getal() != _Right._Myvec._Getal();

			if (_Reload)
				{
				this->_Free_proxy();
				}

			this->_Myvec = _STD move(_Right._Myvec);

			if (_Reload)
				{
				this->_Alloc_proxy();
				}

			this->_Mysize = _Right._Mysize;
			_Right._Mysize = 0;

			if (this->_Myvec._Getal() == _Right._Myvec._Getal())
				{
				this->_Swap_all(_Right);
				}
			}
		return (*this);
		}

	template<class... _Valty>
		void emplace_back(_Valty&&... _Val)
		{	// insert bool at end
		bool _Tmp(_STD forward<_Valty>(_Val)...);
		push_back(_Tmp);
		}

	template<class... _Valty>
		iterator emplace(const_iterator _Where, _Valty&&... _Val)
		{	// insert bool at _Where
		bool _Tmp(_STD forward<_Valty>(_Val)...);
		return (insert(_Where, _Tmp));
		}

	vector(initializer_list<bool> _Ilist,
			const _Alloc& _Al = allocator_type())
		: _Mybase(0, false, _Al)
		{	// construct from initializer_list
		insert(begin(), _Ilist.begin(), _Ilist.end());
		}

	_Myt& operator=(initializer_list<bool> _Ilist)
		{	// assign initializer_list
		assign(_Ilist.begin(), _Ilist.end());
		return (*this);
		}

	void assign(initializer_list<bool> _Ilist)
		{	// assign initializer_list
		assign(_Ilist.begin(), _Ilist.end());
		}

	iterator insert(const_iterator _Where,
			initializer_list<bool> _Ilist)
		{	// insert initializer_list
		return (insert(_Where, _Ilist.begin(), _Ilist.end()));
		}

	~vector() _NOEXCEPT
		{	// destroy the object
		}

	_Myt& operator=(const _Myt& _Right)
		{	// assign from _Right
		if (this != _STD addressof(_Right))
			{	// different, assign it
			this->_Orphan_all();

			const bool _Reload = _Alty::propagate_on_container_copy_assignment::value
				&& this->_Myvec._Getal() != _Right._Myvec._Getal();

			if (_Reload)
				{
				this->_Free_proxy();
				}

			this->_Myvec = _Right._Myvec;

			if (_Reload)
				{
				this->_Alloc_proxy();
				}

			this->_Mysize = _Right._Mysize;
			}

		return (*this);
		}

	void reserve(_CRT_GUARDOVERFLOW size_type _Count)
		{	// determine new minimum length of allocated storage
		this->_Myvec.reserve(this->_Nw(_Count));
		}

	size_type capacity() const _NOEXCEPT
		{	// return current length of allocated storage
		return (this->_Myvec.capacity() * _VBITS);
		}

	iterator begin() _NOEXCEPT
		{	// return iterator for beginning of mutable sequence
		return (iterator(this->_Myvec.data(), this));
		}

	const_iterator begin() const _NOEXCEPT
		{	// return iterator for beginning of nonmutable sequence
		return (const_iterator(this->_Myvec.data(), this));
		}

	iterator end() _NOEXCEPT
		{	// return iterator for end of mutable sequence
		iterator _Tmp = begin();
		if (0 < this->_Mysize)
			_Tmp += this->_Mysize;
		return (_Tmp);
		}

	const_iterator end() const _NOEXCEPT
		{	// return iterator for end of nonmutable sequence
		const_iterator _Tmp = begin();
		if (0 < this->_Mysize)
			_Tmp += this->_Mysize;
		return (_Tmp);
		}

	const_iterator cbegin() const _NOEXCEPT
		{	// return iterator for beginning of nonmutable sequence
		return (begin());
		}

	const_iterator cend() const _NOEXCEPT
		{	// return iterator for end of nonmutable sequence
		return (end());
		}

	const_reverse_iterator crbegin() const _NOEXCEPT
		{	// return iterator for beginning of reversed nonmutable sequence
		return (rbegin());
		}

	const_reverse_iterator crend() const _NOEXCEPT
		{	// return iterator for end of reversed nonmutable sequence
		return (rend());
		}

	void shrink_to_fit()
		{	// reduce capacity
		if (this->_Myvec.capacity() != this->_Myvec.size())
			{	// worth shrinking, do it
			this->_Orphan_all();
			this->_Myvec.shrink_to_fit();
			}
		}

	iterator _Make_iter(const_iterator _Where)
		{	// make iterator from const_iterator
		iterator _Tmp = begin();
		if (0 < this->_Mysize)
			_Tmp += _Where - begin();
		return (_Tmp);
		}

	reverse_iterator rbegin() _NOEXCEPT
		{	// return iterator for beginning of reversed mutable sequence
		return (reverse_iterator(end()));
		}

	const_reverse_iterator rbegin() const _NOEXCEPT
		{	// return iterator for beginning of reversed nonmutable sequence
		return (const_reverse_iterator(end()));
		}

	reverse_iterator rend() _NOEXCEPT
		{	// return iterator for end of reversed mutable sequence
		return (reverse_iterator(begin()));
		}

	const_reverse_iterator rend() const _NOEXCEPT
		{	// return iterator for end of reversed nonmutable sequence
		return (const_reverse_iterator(begin()));
		}

	void resize(_CRT_GUARDOVERFLOW size_type _Newsize, bool _Val = false)
		{	// determine new length, padding with _Val elements as needed
		if (size() < _Newsize)
			_Insert_n(end(), _Newsize - size(), _Val);
		else if (_Newsize < size())
			erase(begin() + _Newsize, end());
		}

	size_type size() const _NOEXCEPT
		{	// return length of sequence
		return (this->_Mysize);
		}

	size_type max_size() const _NOEXCEPT
		{	// return maximum possible length of sequence
		const size_type _Maxsize = this->_Myvec.max_size();
		return (_Maxsize < (size_type)(-1) / _VBITS
			? _Maxsize * _VBITS : (size_type)(-1));
		}

	bool empty() const _NOEXCEPT
		{	// test if sequence is empty
		return (size() == 0);
		}

	_Alloc get_allocator() const _NOEXCEPT
		{	// return allocator object for values
		_Alloc _Ret(this->_Myvec.get_allocator());
		return (_Ret);
		}

	const_reference at(size_type _Off) const
		{	// subscript nonmutable sequence with checking
		if (size() <= _Off)
			_Xran();
		return ((*this)[_Off]);
		}

	reference at(size_type _Off)
		{	// subscript mutable sequence with checking
		if (size() <= _Off)
			_Xran();
		return ((*this)[_Off]);
		}

	const_reference operator[](size_type _Off) const
		{	// subscript nonmutable sequence
		const_iterator _It = begin();
		_It._Advance(_Off);
		return (*_It);
		}

	reference operator[](size_type _Off)
		{	// subscript mutable sequence
		iterator _It = begin();
		_It._Advance(_Off);
		return (*_It);
		}

	reference front()
		{	// return first element of mutable sequence
		return (*begin());
		}

	const_reference front() const
		{	// return first element of nonmutable sequence
		return (*begin());
		}

	reference back()
		{	// return last element of mutable sequence
		return (*(end() - 1));
		}

	const_reference back() const
		{	// return last element of nonmutable sequence
		return (*(end() - 1));
		}

	void push_back(const bool& _Val)
		{	// insert element at end
		insert(end(), _Val);
		}

	void pop_back()
		{	// erase element at end
		erase(end() - 1);
		}

	template<class _Iter>
		enable_if_t<_Is_iterator<_Iter>::value,
			void>
		assign(_Iter _First, _Iter _Last)
		{	// assign [_First, _Last), input iterators
		erase(begin(), end());
		insert(begin(), _First, _Last);
		}

	void assign(_CRT_GUARDOVERFLOW size_type _Count, const bool& _Val)
		{	// assign _Count * _Val
		erase(begin(), end());
		_Insert_n(begin(), _Count, _Val);
		}

	iterator insert(const_iterator _Where, const bool& _Val)
		{	// insert _Val at _Where
		return (_Insert_n(_Where, (size_type)1, _Val));
		}

	iterator insert(const_iterator _Where, _CRT_GUARDOVERFLOW size_type _Count,
		const bool& _Val)
		{	// insert _Count * _Val at _Where
		return (_Insert_n(_Where, _Count, _Val));
		}

	template<class _Iter>
		enable_if_t<_Is_iterator<_Iter>::value,
			iterator>
		insert(const_iterator _Where, _Iter _First, _Iter _Last)
		{	// insert [_First, _Last) at _Where
		size_type _Off = _Where - begin();
		_Insert(_Where, _First, _Last, _Iter_cat_t<_Iter>());
		return (begin() + _Off);
		}

	template<class _Iter>
		void _Insert(const_iterator _Where,
			_Iter _First, _Iter _Last,
				input_iterator_tag)
		{	// insert [_First, _Last) at _Where, input iterators
		size_type _Off = _Where - begin();

		for (; _First != _Last; ++_First, (void)++_Off)
			insert(begin() + _Off, *_First);
		}

	template<class _Iter>
		void _Insert(const_iterator _Where,
			_Iter _First, _Iter _Last,
			forward_iterator_tag)
		{	// insert [_First, _Last) at _Where, forward iterators
		_DEBUG_RANGE(_First, _Last);
		size_type _Count = _STD distance(_First, _Last);
		size_type _Off = _Insert_x(_Where, _Count);
		_STD copy(_First, _Last, begin() + _Off);
		}

	iterator erase(const_iterator _Where_arg)
		{	// erase element at _Where
		iterator _Where = _Make_iter(_Where_arg);
		size_type _Off = _Where - begin();

 #if _ITERATOR_DEBUG_LEVEL == 2
		if (end() <= _Where)
			{
			_DEBUG_ERROR("vector<bool> erase iterator outside range");
			}

		_STD copy(_Where + 1, end(), _Where);
		_Orphan_range(_Off, this->_Mysize);

 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
		_STD copy(_Where + 1, end(), _Where);
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		_Trim(this->_Mysize - 1);
		return (begin() + _Off);
		}

	iterator erase(const_iterator _First_arg,
		const_iterator _Last_arg)
		{	// erase [_First, _Last)
		iterator _First = _Make_iter(_First_arg);
		iterator _Last = _Make_iter(_Last_arg);
		size_type _Off = _First - begin();

		if (_First != _Last)
			{	// worth doing, copy down over hole
 #if _ITERATOR_DEBUG_LEVEL == 2
			if (_Last < _First || end() < _Last)
				{
				_DEBUG_ERROR("vector<bool> erase iterator outside range");
				}

			iterator _Next = _STD copy(_Last, end(), _First);
			size_type _Newsize = _Next - begin();
			_Orphan_range(_Newsize, this->_Mysize);
			_Trim(_Newsize);

 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
			iterator _Next = _STD copy(_Last, end(), _First);
			_Trim(_Next - begin());
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
			}
		return (begin() + _Off);
		}

	void clear() _NOEXCEPT
		{	// erase all elements
		erase(begin(), end());
		}

	void flip() _NOEXCEPT
		{	// toggle all elements
		for (typename _Vectype::iterator _Next = this->_Myvec.begin();
			_Next != this->_Myvec.end(); ++_Next)
			*_Next = (_Vbase)~*_Next;
		_Trim(this->_Mysize);
		}

	void swap(_Myt& _Right)
		{	// exchange contents with _Right
		if (this != _STD addressof(_Right))
			{	// (maybe) swap allocators, swap control information
			this->_Swap_all(_Right);
			this->_Myvec.swap(_Right._Myvec);
			_STD swap(this->_Mysize, _Right._Mysize);
			}
		}

	static void swap(reference _Left, reference _Right) _NOEXCEPT
		{	// swap _Left and _Right vector<bool> elements
		bool _Val = _Left;	// NOT _STD swap

		_Left = _Right;
		_Right = _Val;
		}

	size_t hash() const
		{	// hash bits to size_t value by pseudorandomizing transform
		return (_Hash_seq((const unsigned char *)this->_Myvec.data(),
			this->_Myvec.size() * sizeof (_Vbase)));
		}

	iterator _Insert_n(const_iterator _Where,
		size_type _Count, const bool& _Val)
		{	// insert _Count * _Val at _Where
		size_type _Off = _Insert_x(_Where, _Count);
		_STD fill(begin() + _Off, begin() + (_Off + _Count), _Val);
		return (begin() + _Off);
		}

	size_type _Insert_x(const_iterator _Where, size_type _Count)
		{	// make room to insert _Count elements at _Where
		size_type _Off = _Where - begin();

 #if _ITERATOR_DEBUG_LEVEL == 2
		if (end() < _Where)
			{
			_DEBUG_ERROR("vector<bool> insert iterator outside range");
			}

		bool _Realloc = capacity() - size() < _Count;
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		if (_Count == 0)
			;
		else if (max_size() - size() < _Count)
			_Xlen();	// result too long
		else
			{	// worth doing
			this->_Myvec.resize(this->_Nw(size() + _Count), 0);
			if (empty())
				this->_Mysize += _Count;
			else
				{	// make room and copy down suffix
				iterator _Oldend = end();
				this->_Mysize += _Count;
				_STD copy_backward(begin() + _Off, _Oldend, end());
				}

 #if _ITERATOR_DEBUG_LEVEL == 2
			_Orphan_range(_Realloc ? 0 : _Off, this->_Mysize);
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
			}
		return (_Off);
		}

 #if _ITERATOR_DEBUG_LEVEL == 2
	void _Orphan_range(size_type _Offlo, size_type _Offhi) const
		{	// orphan iterators within specified (inclusive) range
		typedef _Vb_iter_base<_Alty> _Myiterbase;

		_Lockit _Lock(_LOCK_DEBUG);
		auto _Base = const_cast<_Vbase *>(this->_Myvec.data());

		const_iterator **_Pnext = (const_iterator **)this->_Getpfirst();
		if (_Pnext != 0)
			while (*_Pnext != 0)
				{	// test offset from beginning of vector
				size_type _Off = _VBITS * ((*_Pnext)->_Myptr - _Base)
					+ (*_Pnext)->_Myoff;
				if (_Off < _Offlo || _Offhi < _Off)
					_Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
				else
					{	// orphan the iterator
					(*_Pnext)->_Clrcont();
					*_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
					}
				}
		}

 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
	void _Orphan_range(size_type, size_type) const
		{	// orphan iterators within specified (inclusive) range
		}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

	void _Trim(size_type _Size)
		{	// trim base vector to exact length in bits
		if (max_size() < _Size)
			_Xlen();	// result too long
		size_type _Words = this->_Nw(_Size);

		if (_Words < this->_Myvec.size())
			this->_Myvec.erase(this->_Myvec.begin() + _Words,
				this->_Myvec.end());
		this->_Mysize = _Size;
		_Size %= _VBITS;
		if (0 < _Size)
			this->_Myvec[_Words - 1] &= ((_Vbase)(1) << _Size) - 1;
		}

	[[noreturn]] void _Xlen() const
		{	// report a length_error
		_Xlength_error("vector<bool> too long");
		}

	[[noreturn]] void _Xran() const
		{	// report an out_of_range error
		_Xout_of_range("invalid vector<bool> subscript");
		}
	};

template<class _Alloc> inline
	bool operator==(const vector<bool, _Alloc>& _Left,
		const vector<bool, _Alloc>& _Right)
	{	// test for vector equality
	return (_Left.size() == _Right.size()
		&& _STD equal(_Left._Myvec.begin(), _Left._Myvec.end(),
			_Right._Myvec.begin()));
	}

template<class _Alloc> inline
	bool operator!=(const vector<bool, _Alloc>& _Left,
		const vector<bool, _Alloc>& _Right)
	{	// test for vector inequality
	return (!(_Left == _Right));
	}

	// TEMPLATE STRUCT SPECIALIZATION hash
template<class _Alloc>
	struct hash<vector<bool, _Alloc> >
	{	// hash functor
	typedef vector<bool, _Alloc> argument_type;
	typedef size_t result_type;

	size_t operator()(const argument_type& _Keyval) const
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Keyval.hash());
		}
	};
_STD_END

 #pragma pop_macro("new")
 #pragma warning(pop)
 #pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _VECTOR_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:0009 */
